﻿using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class CubeMesh : MonoBehaviour
{
    private Mesh cubeMesh;
    private MeshCollider meshCollider;

    private List<Vector3> vertices;
    private List<int> triangles;

    private void Awake()
    {
        GetComponent<MeshFilter>().mesh = cubeMesh = new Mesh();
        meshCollider = gameObject.AddComponent<MeshCollider>();
        vertices = new List<Vector3>();
        triangles = new List<int>();
    }

    public void TriaggulateCube(Vector3 pos)
    {
        Vector3 v1 = pos + CubeMetrics.cubeVertex[0];
        Vector3 v2 = pos + CubeMetrics.cubeVertex[1];
        Vector3 v3 = pos + CubeMetrics.cubeVertex[2];
        Vector3 v4 = pos + CubeMetrics.cubeVertex[3];
        Vector3 v5 = pos + CubeMetrics.cubeVertex[4];
        Vector3 v6 = pos + CubeMetrics.cubeVertex[5];
        Vector3 v7 = pos + CubeMetrics.cubeVertex[6];
        Vector3 v8 = pos + CubeMetrics.cubeVertex[7];

        for (int i = 0; i < 6; i++)
        {
            AddCubeSurface(v1, v2, v3, v4, v5, v6, v7, v8, (CubeSurface)i);
        }
    }

    public void Apply()
    {
        cubeMesh.SetVertices(vertices);
        cubeMesh.SetTriangles(triangles, 0);
        cubeMesh.RecalculateNormals();
        meshCollider.sharedMesh = cubeMesh;
    }

    public void Clear()
    {
        vertices.Clear();
        triangles.Clear();
        cubeMesh.Clear();
    }

    private void AddCubeSurface(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 v5, Vector3 v6, Vector3 v7, Vector3 v8, CubeSurface surface)
    {
        switch (surface)
        {
            case CubeSurface.up:
                AddSurfaceQuad(v1, v2, v3, v4);
                break;
            case CubeSurface.down:
                AddSurfaceQuad(v6, v5, v8, v7);
                break;
            case CubeSurface.left:
                AddSurfaceQuad(v1, v4, v8, v5);
                break;
            case CubeSurface.right:
                AddSurfaceQuad(v3, v2, v6, v7);
                break;
            case CubeSurface.front:
                AddSurfaceQuad(v2, v1, v5, v6);
                break;
            case CubeSurface.back:
                AddSurfaceQuad(v4, v3, v7, v8);
                break;
        }
    }

    private void AddSurfaceQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4)
    {
        int vertexIndex = vertices.Count;
        vertices.Add(v1);
        vertices.Add(v2);
        vertices.Add(v3);
        vertices.Add(v4);
        triangles.Add(vertexIndex); triangles.Add(vertexIndex + 1); triangles.Add(vertexIndex + 2);
        triangles.Add(vertexIndex); triangles.Add(vertexIndex + 2); triangles.Add(vertexIndex + 3);
    }
}
